<?php
// ini_set("display_errors", "On");//打开错误提示
// ini_set("error_reporting",E_ALL);//显示所有错误
ini_set('memory_limit', '6124M');

use Swoole\Coroutine;

class MysqliDB{
      //私有的属性
      private static $dbcon=false;
      private $host;
      private $port;
      private $user;
      private $pass;
      private $db;
      private $charset;
      private $link;
      //私有的构造方法
      private function __construct($config=array()){
        $this->host = key_exists('host',$config) ? $config['host'] : 'localhost';
        $this->port = key_exists('port', $config)  ? $config['port'] : '3306';
        $this->user = key_exists('user', $config)  ? $config['user'] : 'root';
        $this->pass = key_exists('pass', $config)  ? $config['pass'] : 'root';
        $this->db = key_exists('db', $config)  ? $config['db'] : 'test1';
        $this->charset=isset($arr['charset']) ? $arr['charset'] : 'utf8';
        //连接数据库
        $this->db_connect();
        //选择数据库
        $this->db_usedb();
        //设置字符集
        $this->db_charset();
       }
       //连接数据库
       private function db_connect(){
        $this->link=mysqli_connect($this->host,$this->user,$this->pass,$this->db);
        if(!$this->link){
          echo "数据库连接失败<br>";
          echo "错误编码".mysqli_errno($this->link)."<br>";
          echo "错误信息".mysqli_error($this->link)."<br>";
          exit;
        }
       }
       //设置字符集
        private function db_charset(){
         mysqli_query($this->link,"set names {$this->charset}");
        }
        //选择数据库
       private function db_usedb(){
         mysqli_query($this->link,"use {$this->db}");
       }
       //私有的克隆
       private function __clone(){
         die('clone is not allowed');
       }
       //公用的静态方法
       public static function getIntance(){
         if(self::$dbcon==false){
          self::$dbcon=new self;
         }
         return self::$dbcon;
       }
       //执行sql语句的方法
        public function query($sql){
         $res=mysqli_query($this->link,$sql);
         if(!$res){
          echo "sql语句执行失败<br>";
          echo "错误编码是".mysqli_errno($this->link)."<br>";
          echo "错误信息是".mysqli_error($this->link)."<br>";
         }
         return $res;
       }
       //打印数据
        public function p($arr){
          echo "<pre>";
          print_r($arr);
          echo "</pre>";
        }
        public function v($arr){
        echo "<pre>";
          var_dump($arr);
          echo "</pre>";
        }
        //获得最后一条记录id
        public function getInsertid(){
         return mysqli_insert_id($this->link);
        }
       /**
        * 查询某个字段
        * @param
        * @return string or int
        */
        public function getOne($sql){
         $query=$this->query($sql);
          return mysqli_free_result($query);
        }
        //获取一行记录,return array 一维数组
        public function getRow($sql,$type="assoc"){
         $query=$this->query($sql);
         if(!in_array($type,array("assoc",'array',"row"))){
           die("mysqli_query error");
         }
         $funcname="mysqli_fetch_".$type;
         return $funcname($query);
        }
        //获取一条记录,前置条件通过资源获取一条记录
        public function getFormSource($query,$type="assoc"){
        if(!in_array($type,array("assoc","array","row")))
        {
          die("mysqli_query error");
        }
        $funcname="mysqli_fetch_".$type;
        return $funcname($query);
        }
        //获取多条数据，二维数组
        public function getAll($sql){
         $query=$this->query($sql);
         $list=array();
         while ($r=$this->getFormSource($query)) {
          $list[]=$r;
         }
         return $list;
        }
         /**
         * 定义添加数据的方法
         * @param string $table 表名
         * @param string orarray $data [数据]
         * @return int 最新添加的id
         */
         public function insert($table,$data){
         //遍历数组，得到每一个字段和字段的值
         $key_str='';
         $v_str='';
         foreach($data as $key=>$v){
          if(empty($v)){
           die("error");
         }
            //$key的值是每一个字段s一个字段所对应的值
            $key_str.=$key.',';
            $v_str.="'$v',";
         }
         $key_str=trim($key_str,',');
         $v_str=trim($v_str,',');
         //判断数据是否为空
         $sql="insert into $table ($key_str) values ($v_str)";
         $this->query($sql);
        //返回上一次增加操做产生ID值
         return $this->getInsertid();
       }
       /*
        * 删除一条数据方法
        * @param1 $table, $where=array('id'=>'1') 表名 条件
        * @return 受影响的行数
        */
        public function deleteOne($table, $where){
          if(is_array($where)){
            foreach ($where as $key => $val) {
              $condition = $key.'='.$val;
            }
          } else {
            $condition = $where;
          }
          $sql = "delete from $table where $condition";
          $this->query($sql);
          //返回受影响的行数
          return mysqli_affected_rows($this->link);
        }
        /*
        * 删除多条数据方法
        * @param1 $table, $where 表名 条件
        * @return 受影响的行数
        */
        public function deleteAll($table, $where){
          if(is_array($where)){
            foreach ($where as $key => $val) {
              if(is_array($val)){
                $condition = $key.' in ('.implode(',', $val) .')';
              } else {
                $condition = $key. '=' .$val;
              }
            }
          } else {
            $condition = $where;
          }
          $sql = "delete from $table where $condition";
          $this->query($sql);
          //返回受影响的行数
          return mysqli_affected_rows($this->link);
        }
       /**
        * [修改操作description]
        * @param [type] $table [表名]
        * @param [type] $data [数据]
        * @param [type] $where [条件]
        * @return [type]
        */
       public function update($table,$data,$where){
         //遍历数组，得到每一个字段和字段的值
         $str='';
        foreach($data as $key=>$v){
         $str.="$key='$v',";
        }
        $str=rtrim($str,',');
        //修改SQL语句
        $sql="update $table set $str where $where";
        echo $sql;
        $this->query($sql);
        //返回受影响的行数
        return mysqli_affected_rows($this->link);
       }
}
 
$serv = new Swoole\Server('127.0.0.1', 9501);

function password($serv, $path, $passwd,$flag )
{
    $arr = file($path);
    foreach ($arr as $item) {
         $serv->task([$passwd,$item,$flag]);
        // if (password_verify($item, $passwd)) {
        //     echo $item;
        // }
    }
}
static $flag  = 0;

$table = new \Swoole\Table(1024 * 1024*10);
$table->column('id', \Swoole\Table::TYPE_INT);
$table->create();
 $table->set('tab-1', ['id' => 0]);


//设置异步任务的工作进程数量
$serv->set([
  'worker_num' => 8, //设置工作进程
  'reactor_num' => 4, //线程组个数,最大不得超过cpu*4
  'max_request' => 1000,
  'task_worker_num' => 32,]); //异步工作进程]);

//此回调函数在worker进程中执行
$serv->on('Receive', function ($serv, $fd, $reactor_id, $data) use($table)  {
    //投递异步任务
    $task_id = $serv->task($data);
    var_dump($data);

  // if ($table->exist('tab-1')) {
  //     $table->set('tab-1', ['id' => 1]);
  //         echo  $table->get('student-1', 'id');
  // }
  # $flag = true;
  
    // $db = MysqliDB::getIntance();
    $i = 0;
    // $list = $db->getAll('SELECT DISTINCT password from tab1  where ispj = 0');
    #echo count($list);
    // foreach ($list as $key => $value) {
    # code...
    #echo "New AsyncTask[id={$task_id}]" . PHP_EOL;
       $passwd = '';
       $path = '/Users/apple/Desktop/hacker/passworddict/top19576.txt';
         $i++;
        $table->set('tab-' . $i, ['id' => 1]);
        $arr = file($path);
          $k =0;
         foreach ($arr as $item) {
        //   if($k > 30){
        //       $k = 0;
        //       sleep(1);
        //   }
          $k++;
          $serv->task([$passwd, $item, $i],$k);
          
          // if (password_verify($item, $passwd)) {
          //     echo $item;
          }
        // }
       # password($serv, '/Users/apple/Desktop/hacker/passworddict/top19576.txt', $value['password'],$i);
    // }
  

    // echo "Dispatch AsyncTask: id={$task_id}\n";
    
});
 
//处理异步任务(此回调函数在task进程中执行)
$serv->on('Task', function ($serv, $task_id, $reactor_id, $data)  use ($flag) {
    #   echo "New AsyncTask[id={$reactor_id}]" . PHP_EOL;
  //返回任务执行的结果
  // $key = $data[2];
  // if (!$table->exist('tab-'. $key)) {
  //   $serv->finish("0");
  //   return;
  // }
   // $flag = $table->get('tab-'.$key, 'id');
    // if($flag){
        $passwd = trim($data[0]);
        $item = trim($data[1]);
        #echo $item . PHP_EOL;
        if(password_verify($item, $passwd)){
           $flag = 1;
           echo $passwd;
         }
            // $db = MysqliDB::getIntance();
            // $db->update('tab1',['realpassword'=> $item, 'ispj'=>1], " password='{$passwd}'");
            // $table->del('tab-' . $key);
           # $serv->finish($key."");
             
        // }else
        if($item == 'ziyouzizai'){ //到最后一个都破不到，代表无法破解
          echo '无法破解';
        //     $db = MysqliDB::getIntance();
        //     $db->update('tab1', ['realpassword' => $item], " ispj='-1'");   
         }

    // } 
  
  # $serv->finish("0");
    
});

//处理异步任务的结果(此回调函数在worker进程中执行)
$serv->on('Finish', function ($serv, $task_id, $data)   use ($table){
   
    # echo  $data;
});
$serv->on('start', function ($serv) {
   echo "Swoole http server is started at http://127.0.0.1:9501\n";
    // $db = MysqliDB::getIntance();
    // $list = $db->getAll('select * from tab1');
    // var_dump($list);
});
$serv->start();

// password_hash('qq123456')


// $http = new Swoole\Http\Server('127.0.0.1', 9501);

//  $http->on('start', function ($server) {
//         echo "Swoole http server is started at http://127.0.0.1:9501\n";
//     password($server, '/Users/apple/Desktop/hacker/passworddict/top19576.txt', '$2y$10$SGVk974/QghYWQaUuay0v.iM0brzEHpMLALem.3GDdsb3Iq9DwFZO');


//  });
//   $http->on('request', function ($request, $response) {
//         $response->header('Content-Type', 'text/plain');
        
// 		$response->end('Hello World');

//     });
// $http->start();

